// UI Elements
const ui = {
  elements: {
    toggleSwitch: null,
    simpleModeSwitch: null,
    cssModeSwitch: false,
    statusMessage: null,
    xpathContainer: null,
    xpathList: null,
    xpathInput: null,
    xpathMatchCount: null,
    matchCount: null,
  },

  initialize() {
    // Get DOM elements
    this.elements.toggleSwitch = document.getElementById("toggleSwitch");
    this.elements.simpleModeSwitch = document.getElementById("simpleMode");
    this.elements.cssModeSwitch = document.getElementById("cssMode");
    this.elements.statusMessage = document.getElementById("statusMessage");
    this.elements.xpathContainer = document.getElementById("xpathContainer");
    this.elements.xpathList = document.getElementById("xpathList");
    this.elements.xpathInput = document.getElementById("xpathInput");
    this.elements.xpathMatchCount = document.getElementById("xpathMatchCount");
    this.elements.matchCount = document.getElementById("matchCount");
  },

  showErrorState(message) {
    this.elements.statusMessage.textContent =
      message || "Cannot run on this page";
    this.elements.statusMessage.classList.add("text-red-600");
    this.elements.toggleSwitch.disabled = true;
  },

  updateStatus(isActive) {
    this.elements.toggleSwitch.checked = isActive;
    this.elements.statusMessage.textContent = isActive
      ? "Element selection is active"
      : "Element selection is inactive";

    if (isActive) {
      this.elements.statusMessage.classList.add("text-indigo-600");
      this.elements.statusMessage.classList.remove("text-red-600");
    } else {
      this.elements.statusMessage.classList.remove("text-indigo-600");
      this.elements.statusMessage.classList.remove("text-red-600");
      this.elements.xpathContainer.classList.add("hidden");
    }
  },
};

// XPath display and management
const xpathManager = {
  currentElementData: null,
  isSimpleMode: true,
  isCssMode: false,

  displayElementData(data) {
    this.currentElementData = data;

    // Check if we have empty XPaths
    if (
      !data.xpaths ||
      data.xpaths.length === 0 ||
      data.elementHasEmptyXPaths
    ) {
      return;
    }

    ui.elements.xpathContainer.classList.remove("hidden");

    // Clear previous XPaths
    ui.elements.xpathList.innerHTML = "";

    // Update the header text based on mode
    const headerElement = document.querySelector("#selectorHeader");
    if (headerElement) {
      headerElement.textContent = this.isCssMode
        ? "Generated CSS Selectors:"
        : "Generated XPaths:";
    }

    let typesToShow;
    // Group XPaths by type
    const xpathsByType = this.groupXPathsByType(data.xpaths);
    if (this.isSimpleMode) {
      typesToShow = ["Optimized"];
    } else {
      typesToShow = Object.keys(xpathsByType);
    }

    // Check if we have any XPaths in the simple mode categories
    if (this.isSimpleMode) {
      const hasSimpleModeXPaths = typesToShow.some(
        (type) => xpathsByType[type] && xpathsByType[type].length > 3
      );

      // If no XPaths found in simple mode, automatically switch to full mode
      if (!hasSimpleModeXPaths) {
        this.switchToFullMode(xpathsByType);
        typesToShow = Object.keys(xpathsByType);
      }
    }

    // Create XPath list with categories
    this.renderXPathCategories(typesToShow, xpathsByType);

    // Scroll to the top of the XPath list
    ui.elements.xpathList.scrollTop = 0;
  },

  groupXPathsByType(xpaths) {
    const xpathsByType = {
      "ID-based": [],
      "Attribute-based": [],
      "Text-based": [],
      "Class-based": [],
      "Position-based": [],
      Optimized: [],
      Absolute: [],
    };

    // Categorize XPaths
    xpaths.forEach(function (xpathInfo) {
      if (xpathInfo.xpath) {
        const type = xpathInfo.type || "Other";
        if (xpathsByType[type]) {
          xpathsByType[type].push(xpathInfo);
        } else {
          xpathsByType["Other"] = [xpathInfo];
        }
      }
    });

    return xpathsByType;
  },

  switchToFullMode(xpathsByType) {
    // Update the UI to reflect the mode change
    this.isSimpleMode = false;
    ui.elements.simpleModeSwitch.checked = false;

    // Show a notification about the mode switch
    const modeChangeNotice = document.createElement("div");
    modeChangeNotice.className =
      "text-blue-600 text-xs p-2 bg-blue-50 rounded-md mb-2 notice";
    modeChangeNotice.textContent =
      "Automatically switched to Full Mode to show more XPath options";
    ui.elements.xpathList.appendChild(modeChangeNotice);
  },

  renderXPathCategories(typesToShow, xpathsByType) {
    for (const type of typesToShow) {
      const xpaths = xpathsByType[type] || [];
      if (xpaths.length > 0) {
        // Create category header
        const categoryHeader = document.createElement("div");
        categoryHeader.className =
          "text-sm font-medium text-gray-700 mt-3 mb-1";
        categoryHeader.textContent = type;
        ui.elements.xpathList.appendChild(categoryHeader);

        // Add XPaths in this category
        xpaths.forEach((xpathInfo) => {
          const xpathItem = this.createXPathItem(
            xpathInfo.xpath,
            xpathInfo.description
          );
          ui.elements.xpathList.appendChild(xpathItem);
        });
      }
    }
  },

  createXPathItem(xpath, description) {
    const xpathItem = document.createElement("div");
    xpathItem.className = "bg-gray-50 p-2 rounded border border-gray-200";

    // Create a container for the XPath content and button
    const container = document.createElement("div");
    container.className = "flex-container";

    // Create the content section (left side)
    const xpathContent = document.createElement("div");
    xpathContent.className = "flex-content";

    const xpathText = document.createElement("div");
    xpathText.className = "text-xs font-mono overflow-x-auto mb-1 xpath-text";
    xpathText.setAttribute("title", xpath);
    xpathText.textContent = xpath;

    const xpathDescription = document.createElement("div");
    xpathDescription.className = "text-xs text-gray-500 italic";
    xpathDescription.textContent = description || "";

    // Create the button section (right side)
    const buttonContainer = document.createElement("div");
    buttonContainer.className = "flex space-x-2";

    // Create Code button
    const codeButton = document.createElement("button");
    codeButton.className =
      "text-xs bg-indigo-500 text-white px-2 py-1 rounded hover:bg-indigo-600 transition-colors focus:outline-none code-button";
    codeButton.style.border = "none";
    codeButton.textContent = "Code";
    codeButton.addEventListener("click", () =>
      this.copyCodeToClipboard(xpath, codeButton)
    );

    // Create Copy button
    const copyButton = document.createElement("div");
    copyButton.className = "text-xs px-2 py-1 rounded copy-button";
    copyButton.style.border = "none";
    const img = document.createElement("img");
    img.src = "./images/copy.svg";
    img.alt = "Copy";
    img.style.width = "16px";
    img.style.height = "16px";
    copyButton.appendChild(img);
    copyButton.addEventListener("click", () =>
      this.copyXPathToClipboard(xpath, copyButton)
    );

    // Assemble the components
    xpathContent.appendChild(xpathText);
    if (description) {
      xpathContent.setAttribute("title", description);
      xpathContent.appendChild(xpathDescription);
    }

    buttonContainer.appendChild(codeButton);
    buttonContainer.appendChild(copyButton);

    container.appendChild(xpathContent);
    container.appendChild(buttonContainer);
    xpathItem.appendChild(container);

    return xpathItem;
  },

  showTips(button) {
    // Create and show success tip
    const tip = document.createElement("div");
    tip.className =
      "success-tip absolute bg-gray-800 text-white text-xs px-2 py-1 rounded";
    tip.textContent = "Copied!";
    tip.style.zIndex = "1000";

    // Position the tip near the button
    const buttonRect = button.getBoundingClientRect();
    const scrollTop =
      document.documentElement.scrollTop || document.body.scrollTop;
    tip.style.top = `${buttonRect.bottom + scrollTop + 5}px`;
    tip.style.left = `${buttonRect.left}px`;

    document.body.appendChild(tip);

    // Remove tip after animation
    setTimeout(() => {
      tip.style.opacity = "0";
      setTimeout(() => document.body.removeChild(tip), 200);
    }, 1000);
  },

  copyXPathToClipboard(xpathOrCss, copyButton) {
    navigator.clipboard.writeText(xpathOrCss).then(function () {
      xpathManager.showTips(copyButton);
    });
  },

  copyCodeToClipboard(xpathOrCss, codeButton) {
    // Generate code based on current mode (XPath or CSS)
    let code;
    if (this.isCssMode) {
      code = `cy.get('${xpathOrCss}')`;
    } else {
      code = `cy.xpath('${xpathOrCss}')`;
    }

    navigator.clipboard.writeText(code).then(function () {
      xpathManager.showTips(codeButton);
    });
  },

  clearXPaths() {
    this.currentElementData = null;
    ui.elements.xpathContainer.classList.add("hidden");
    ui.elements.xpathList.innerHTML = "";
  },
};

// Communication with background script and content script
const communication = {
  checkPageCompatibility() {
    try {
      chrome.runtime.sendMessage(
        { action: "checkPageCompatibility" },
        function (response) {
          if (chrome.runtime.lastError) {
            console.error(
              "Error checking page compatibility:",
              chrome.runtime.lastError
            );
            ui.showErrorState("Error checking page compatibility");
            return;
          }

          if (!response || response.canRun === false) {
            ui.showErrorState(
              response ? response.reason : "Cannot run on this page"
            );
            return;
          }

          // Page is compatible, check if the extension is already active
          communication.checkExtensionStatus();

          // Check if there's any recently selected element data
          communication.checkForRecentElementData();
        }
      );
    } catch (error) {}
  },

  checkExtensionStatus() {
    chrome.tabs.query({ active: true, currentWindow: true }, function (tabs) {
      if (tabs && tabs.length > 0) {
        try {
          chrome.tabs.sendMessage(
            tabs[0].id,
            { action: "getStatus" },
            function (response) {
              if (chrome.runtime.lastError) {
                return;
              }

              if (response) {
                if (response.canRun === false) {
                  ui.showErrorState(
                    "Content script reports it cannot run on this page"
                  );
                  return;
                }

                if (response.isActive) {
                  ui.updateStatus(true);
                }
              }
            }
          );
        } catch (error) {}
      }
    });
  },

  checkForRecentElementData() {
    try {
      chrome.runtime.sendMessage(
        { action: "getLastSelectedElement" },
        function (response) {
          if (chrome.runtime.lastError) {
            return;
          }

          if (response && response.success && response.data) {
            // Update CSS mode state from stored data
            if (response.data.isCssMode !== undefined) {
              xpathManager.isCssMode = response.data.isCssMode;
              ui.elements.cssModeSwitch.checked = response.data.isCssMode;
            }

            if (response.data.matchData) {
              ui.elements.xpathMatchCount.classList.remove("hidden");
              ui.elements.matchCount.textContent =
                response.data.matchData.count;
              ui.elements.xpathInput.value = response.data.matchData.xpath;
            }

            // Use the appropriate selectors based on current mode
            if (xpathManager.isCssMode && response.data.cssSelectors) {
              response.data.xpaths = response.data.cssSelectors;
            } else if (
              !xpathManager.isCssMode &&
              response.data.xpathSelectors
            ) {
              response.data.xpaths = response.data.xpathSelectors;
            }
            xpathManager.displayElementData(response.data);
          }
        }
      );
    } catch (error) {}
  },

  activateExtension() {
    chrome.tabs.query({ active: true, currentWindow: true }, function (tabs) {
      if (tabs && tabs.length > 0) {
        try {
          chrome.tabs.sendMessage(
            tabs[0].id,
            {
              action: "activate",
              isCssMode: xpathManager.isCssMode,
            },
            function (response) {
              if (chrome.runtime.lastError) {
                ui.elements.toggleSwitch.checked = false;
                ui.elements.statusMessage.textContent =
                  "Error: Cannot activate on this page";
                ui.elements.statusMessage.classList.add("text-red-600");
                return;
              }

              if (response) {
                if (response.canRun === false) {
                  ui.elements.toggleSwitch.checked = false;
                  ui.showErrorState(
                    "Content script reports it cannot run on this page"
                  );
                  return;
                }

                // Update CSS mode state if provided in the response
                if (response.isCssMode !== undefined) {
                  xpathManager.isCssMode = response.isCssMode;
                  ui.elements.cssModeSwitch.checked = response.isCssMode;
                }

                ui.updateStatus(true);

                // Notify background script that extension is activated
                chrome.runtime.sendMessage({ action: "activate" });
              } else {
                ui.elements.toggleSwitch.checked = false;
                ui.elements.statusMessage.textContent =
                  "Error: No response from page";
                ui.elements.statusMessage.classList.add("text-red-600");
              }
            }
          );
        } catch (error) {
          console.error("Error activating extension:", error);
          ui.elements.toggleSwitch.checked = false;
          ui.elements.statusMessage.textContent = "Error: " + error.message;
          ui.elements.statusMessage.classList.add("text-red-600");
        }
      }
    });
  },

  deactivateExtension() {
    chrome.tabs.query({ active: true, currentWindow: true }, function (tabs) {
      if (tabs && tabs.length > 0) {
        try {
          chrome.tabs.sendMessage(
            tabs[0].id,
            { action: "deactivate" },
            function (response) {
              if (chrome.runtime.lastError) {
                return;
              }

              ui.updateStatus(false);

              // Clear XPath data when deactivated
              chrome.runtime.sendMessage({ action: "clearXPaths" });
              communication.clearHighlightedElements();
            }
          );
        } catch (error) {
          console.error("Error deactivating extension:", error);
        }
      }
    });
  },

  searchXPath() {
    const expression = ui.elements.xpathInput.value.trim();
    if (!expression) {
      return;
    }

    chrome.tabs.query({ active: true, currentWindow: true }, function (tabs) {
      if (tabs && tabs.length > 0) {
        try {
          chrome.tabs.sendMessage(
            tabs[0].id,
            { action: "searchXPathAndCss", xpathAndCss: expression },
            function (response) {
              if (chrome.runtime.lastError) {
                ui.elements.xpathMatchCount.classList.remove("hidden");
                ui.elements.matchCount.textContent =
                  "Error: " + chrome.runtime.lastError.message;
                return;
              }

              if (response && response.success) {
                ui.elements.xpathMatchCount.classList.remove("hidden");
                ui.elements.matchCount.textContent = response.count;
                chrome.runtime.sendMessage({
                  action: "saveMatchData",
                  data: { xpath: expression, count: response.count },
                });
              } else {
                ui.elements.xpathMatchCount.classList.remove("hidden");
                ui.elements.matchCount.textContent =
                  "Error: " + (response ? response.error : "Unknown error");
              }
            }
          );
        } catch (error) {
          console.error("Error searching XPath:", error);
          ui.elements.xpathMatchCount.classList.remove("hidden");
          ui.elements.matchCount.textContent = "Error: " + error.message;
        }
      }
    });
  },
  clearHighlightedElements() {
    // Clear the input field
    ui.elements.xpathInput.value = "";
    // Hide the match count display
    ui.elements.xpathMatchCount.classList.add("hidden");
    chrome.tabs.query({ active: true, currentWindow: true }, function (tabs) {
      if (tabs && tabs.length > 0) {
        try {
          chrome.tabs.sendMessage(
            tabs[0].id,
            { action: "clearHighlightedElements" },
            function (response) {
              if (chrome.runtime.lastError) {
                return;
              }
            }
          );
        } catch (error) {}
      }
    });
    chrome.runtime.sendMessage({ action: "clearMatchData" });
  },
};

// Event handlers
const eventHandlers = {
  setupEventListeners() {
    // Toggle extension activation
    ui.elements.toggleSwitch.addEventListener("change", function () {
      if (ui.elements.toggleSwitch.disabled) return;

      if (ui.elements.toggleSwitch.checked) {
        communication.activateExtension();
      } else {
        communication.deactivateExtension();
      }
    });

    // Toggle simple mode
    ui.elements.simpleModeSwitch.addEventListener("change", function () {
      xpathManager.isSimpleMode = ui.elements.simpleModeSwitch.checked;

      // If we have current data, redisplay it with the new mode
      if (xpathManager.currentElementData) {
        xpathManager.displayElementData(xpathManager.currentElementData);
      }
    });

    // Toggle CSS mode
    ui.elements.cssModeSwitch.addEventListener("change", function () {
      xpathManager.isCssMode = ui.elements.cssModeSwitch.checked;
      let count = xpathManager.isCssMode
        ? xpathManager.currentElementData.cssSelectors.length
        : xpathManager.currentElementData.xpathSelectors.length;
      // Save CSS mode setting to storage
      chrome.runtime.sendMessage({
        action: "saveSettings",
        settings: { isCssMode: xpathManager.isCssMode, count },
      });

      // Send message to content script about mode change
      chrome.tabs.query({ active: true, currentWindow: true }, function (tabs) {
        if (tabs && tabs.length > 0) {
          try {
            chrome.tabs.sendMessage(
              tabs[0].id,
              { action: "setCssMode", isCssMode: xpathManager.isCssMode },
              function (response) {
                if (chrome.runtime.lastError) {
                  return;
                }
              }
            );
          } catch (error) {}
        }
      });

      // If we have current data, switch to the appropriate selectors
      if (xpathManager.currentElementData) {
        // Update the CSS mode in the current data
        xpathManager.currentElementData.isCssMode = xpathManager.isCssMode;

        // Use the appropriate selectors based on mode
        if (
          xpathManager.isCssMode &&
          xpathManager.currentElementData.cssSelectors
        ) {
          xpathManager.currentElementData.xpaths =
            xpathManager.currentElementData.cssSelectors;
        } else if (
          !xpathManager.isCssMode &&
          xpathManager.currentElementData.xpathSelectors
        ) {
          xpathManager.currentElementData.xpaths =
            xpathManager.currentElementData.xpathSelectors;
        }

        // Redisplay with the updated selectors
        xpathManager.displayElementData(xpathManager.currentElementData);
      }
    });

    // XPath input search button is removed, only using Enter key now

    // XPath input enter key
    ui.elements.xpathInput.addEventListener("keyup", function (event) {
      if (event.key === "Enter") {
        communication.searchXPath();
      }
    });

    // Reset button click
    document
      .getElementById("resetButton")
      .addEventListener("click", function () {
        communication.clearHighlightedElements();
      });

    // Listen for messages from the content script
    chrome.runtime.onMessage.addListener(function (
      request,
      sender,
      sendResponse
    ) {
      if (request.action === "elementSelected") {
        // Update CSS mode state if provided in the request
        if (request.isCssMode !== undefined) {
          xpathManager.isCssMode = request.isCssMode;
          ui.elements.cssModeSwitch.checked = request.isCssMode;
        }
        xpathManager.displayElementData(request);
        sendResponse({ success: true });
      } else if (request.action === "clearXPaths") {
        // Clear XPath display
        xpathManager.clearXPaths();
        sendResponse({ success: true });
      }
      return true;
    });
  },
};

// Initialize the popup
document.addEventListener("DOMContentLoaded", function () {
  // Initialize UI
  ui.initialize();

  // Setup event listeners
  eventHandlers.setupEventListeners();

  // Check page compatibility
  communication.checkPageCompatibility();
});
